package aspects;


import generique.Log;

import javax.crypto.SealedObject;

import serveur.KernelServeur;

import commun.Chiffrement;
import commun.Paquet;
import commun.PaquetRequete;



/**
 * 
 * Aspect permettant de logger l'activité du serveur.
 * 
 * @author Valentin Brémond
 * 
 * @version 1.0
 *
 */
public privileged aspect LogServeurAspect
{
	// On récupère l'instance de log
	Log log = Log.getInstance ();
	
	
	
	/**
	 * Au démarrage du serveur.
	 */
	KernelServeur around () : call (KernelServeur.new (..))
	{
		KernelServeur retour;
		
		log.info ("Démarrage du serveur...");
		
		retour = proceed ();
		
		log.info ("Serveur démarré.");
		log.info ("Stub RMI disponible à l'adresse '" + retour.urlRMI + "'.");
		
		return retour;
	}
	
	
	
	/**
	 * À l'extinction du serveur.
	 */
	before () : call (* System.exit (..))
	{
		if (thisEnclosingJoinPointStaticPart.getSignature ().getDeclaringType ().equals (KernelServeur.class))
		{
			log.info ("Arrêt du serveur.");
		}		
	}
	
	
	
	/**
	 * Lors du calcul Diffie-Hellman.
	 */
	long around (long g, long n, long x) : execution (long diffieHellman (long, long, long)) && args (g, n, x) && target (KernelServeur)
	{
		long retour = 0;
		
		log.info ("Un client veut se connecter.");
		log.info ("Calcul de la clé symétrique avec les paramètres :");
		log.info ("G = " + g + ", n = " + n + ", X = " + x);
		
		retour = proceed (g, n, x);
		
		log.info ("Clé symétrique calculée par le serveur : " + ((KernelServeur) thisJoinPoint.getTarget ()).cleDiffieHellman);
		
		return retour;
	}
	
	
	
	/**
	 * Lors de la vérification d'authenticité.
	 */
	SealedObject around () : execution (SealedObject verifierAuthenticite (SealedObject)) && target (KernelServeur)
	{
		SealedObject retour;
		
		log.info ("Vérification de l'authenticité du client...");
		
		retour = proceed ();
		
		if (retour == null)
		{
			log.warning ("Impossible d'authentifier le client.");
		}
		else
		{
			log.info ("Le client est bien authentifié.");
		}
		
		return retour;
	}
	
	
	
	SealedObject around () : execution (SealedObject effectuerRequete (SealedObject)) && target (KernelServeur)
	{
		SealedObject retour;
		
		log.info ("Requête entrante.");
		
		retour = proceed ();
		
		if (retour == null)
		{
			log.warning ("Un client non identifié tente d'effectuer une requête.");
		}
		else
		{
			log.info ("Un réponse à la requête vient d'être renvoyée.");
		}
		
		return retour;
	}
	
	
	
	/**
	 * Lors d'une requête.
	 */
	after () returning (PaquetRequete paquet) : execution (Paquet Chiffrement.dechiffrer (..))
	{
		log.info ("Paquet requête entrant : '" + paquet.getRequete () + "'.");
	}
	
	
	
	/**
	 * Lors de l'envoi du message en clair (FINS DE TEST UNIQUEMENT).
	 */
	String around (String message) : execution (String testEnvoiMessageClair (String)) && args (message)
	{
		String retour;
		
		log.info ("Réception d'un message en clair : '" + message + "'.");
		
		retour = proceed (message);
		
		log.info ("Réponse du serveur : '" + retour + "'.");
		
		return retour;
	}
}
